package com.ruoyi.wechat;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.member.service.IMemberService;
import com.ruoyi.memberSer.domain.MemberSer;
import com.ruoyi.memberSer.service.IMemberSerService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.wechat.service.WeChatUserService;
import com.ruoyi.wechat.util.CommonUtil;
import com.ruoyi.wechat.util.MessageUtil;
import com.ruoyi.wechat.util.RequestUtil;
import com.ruoyi.wechat.util.SignUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 对外接口Controller
 *
 * @author jiuyou
 * @date 2021-03-02
 */
@RestController
@RequestMapping("/weChat")
public class WechatController {

    @Autowired
    private WeChatUserService weChatUserService;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private IMemberSerService memberSerService;
    @Autowired
    private ISysConfigService sysConfigService;
    @GetMapping (value = "boundWechat")
    public void boundWechat(HttpServletRequest request, HttpServletResponse response, String APPKEY) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        String token =sysConfigService.selectConfigByKey(APPKEY+"_TOKEN") ;//ConfigReaderUtil.getKeyValue("TOKEN");// 公众号token 未来配置在库中
        PrintWriter out = null;
        try {
            out = response.getWriter();
            if (SignUtil.checkSignature(token, signature, timestamp, nonce)) {
                out.print(echostr);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            out.close();
        }
    }
    /**
     *
     * @Description: TODO(处理微信消息响应)
     * @author cuihang
     * @date 2015-5-20 下午1:58:05
     * @param request
     * @param response
     */
    @PostMapping(value = "boundWechat")
    public void wechatServer(HttpServletRequest request, HttpServletResponse response, String APPKEY) throws Exception {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        final Map<String, String> requestMap = MessageUtil.parseXml(request);
        final String realpath = request.getSession().getServletContext().getRealPath("/");
        new Thread() {
            public void run() {
                try {
                   // autoApplyService.AutoApply(requestMap,realpath);
                    String fromUserName = requestMap.get("FromUserName");
                        // 调用parseXml方法解析请求消息
                        // 消息类型
                        String msgType = requestMap.get("MsgType");
                        String Event = requestMap.get("Event");
                        if (msgType.equals("event")) {
                            //事件
                            if (Event.equals("subscribe")){
                                //关注
                                handleUser(fromUserName,APPKEY,Event);
                            }
                            if (Event.equals("unsubscribe")){
                                //取消关注
                                handleUser(fromUserName,APPKEY,Event);
                            }

                        }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }.start();
        String returnXml = "success";
        PrintWriter out;
        try {
            out = response.getWriter();
            out.print(returnXml);
            out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     *
     * @param openid
     * @param APPKEY
     * @param Event 关注或者未关注
     */
    private void handleUser(String openid,String APPKEY,String Event){
        JSONObject jsonInfo= weChatUserService.getWeChatUserInfo(openid,APPKEY);
        System.out.println(jsonInfo.toJSONString());
        MemberSer memberSerParm=new MemberSer();
        memberSerParm.setOpenId(openid);
        List<MemberSer> list= memberSerService.selectMemberSerList(memberSerParm);
        MemberSer memberSer=new MemberSer();
        String unionid=jsonInfo.getString("unionid");
        if(list.size()>0){
            //
            MemberSer  memberSerTemp=list.get(0);
            memberSer.setId(memberSerTemp.getId());
            if(!StringUtils.isEmpty(unionid)){
                memberSer.setUnionId(unionid);
            }

        }else{
            //没有用户
            memberSer=new MemberSer();
            memberSer.setOpenId(jsonInfo.getString("openid"));
            memberSer.setUnionId(unionid);

        }
        memberSer.setSubscribe(jsonInfo.getLong("subscribe"));
        Long subscribe_time=jsonInfo.getLong("subscribe_time");
        if(null!=subscribe_time){
            memberSer.setSubscribeTime(new Date(subscribe_time*1000L));
        }
        String subscribe_scene=jsonInfo.getString("subscribe_scene");
        if(!StringUtils.isEmpty(subscribe_scene)){
            memberSer.setSubscribeScene(subscribe_scene);
        }
        if(null!=memberSer.getId()){
            memberSerService.updateMemberSer(memberSer);
        }else{
            memberSerService.insertMemberSer(memberSer);
        }
    }
    /**
     * @Description: TODO(微信Oauth2认证，请求req并传过去code)
     * @author cuihang
     * @date 2015-10-10 下午4:58:58
     * @param request
     * @param response
     * @param req
     */
//    @RequestMapping(value = "oauth2req")
//    public void oauth2req(HttpServletRequest request, HttpServletResponse response, String req,String APPKEY) {
//        try {
//            if (null != req) {
//                String QZ = RequestUtil.getScheme(request)+"://"+request.getServerName()+RequestUtil.getPortByReq(request)+request.getContextPath()+"/";
//                String reql = QZ+sysConfigService.selectConfigByKey(req);
//                String appid = sysConfigService.selectConfigByKey(APPKEY+"_APPKEY");
//                String reUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + URLEncoder.encode(reql, "utf-8") + "&response_type=code&scope=snsapi_base&state=#wechat_redirect";
//                response.sendRedirect(reUrl);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }

//    public static String  getPortByReq(HttpServletRequest request){
//        String result="";
//        int locport=request.getLocalPort();
//        if(locport==9090){
//            result=":443";
//        }
//        return result;
//    }

    /**
     *
     * @Description: TODO(通过Oauth2认证并跳入指定页面)
     * @author cuihang
     * @date 2015-10-13 下午6:15:44
     * @param request
     * @param response
     * @param req
     */
    @RequestMapping(value = "oauth2j")
    public void oauth2j(HttpServletRequest request, HttpServletResponse response, String req,String APPKEY) {
        try {
            Map<String, String> param = CommonUtil.translateMap(request.getParameterMap());
            param.remove("req");
            if(null!=req){
                param.put("reqUrl",sysConfigService.selectConfigByKey(req));
            }

            StringBuffer pareStr = new StringBuffer();
            int numtemp = 0;
            for (String key : param.keySet()) {
                if (numtemp == 0) {
                    pareStr.append(key).append("=").append(param.get(key));
                } else {
                    pareStr.append("&").append(key).append("=").append(param.get(key));
                }
                numtemp++;
            }
            String reql = RequestUtil.getScheme(request)+"://"+request.getServerName()+RequestUtil.getPortByReq(request)+ request.getContextPath()+"/weChat/oauth2jOpenid?" + pareStr.toString();
            String appid = sysConfigService.selectConfigByKey(APPKEY+"_APPKEY");
            String reUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + URLEncoder.encode(reql, "utf-8") + "&response_type=code&scope=snsapi_base&state=#wechat_redirect";
            response.sendRedirect(reUrl);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description: TODO(微信请求的页面并将openid传入页面)
     * @author cuihang
     * @date 2015-10-13 下午6:14:19
     * @param request
     * @param response
     * @param code
     * @return
     */
    @RequestMapping(value = "oauth2jOpenid")
    public void oauth2jOpenid(HttpServletRequest request, HttpServletResponse response, String code,String reqUrl) throws Exception {

        Map<String, String> param = CommonUtil.translateMap(request.getParameterMap());
        param.remove("code");
        param.remove("state");
        param.remove("reqUrl");
        JSONObject jso = weChatUserService.converWechatOpenId(code,param.get("APPKEY"));
        String openid=jso.getString("openid");
        request.getSession().setAttribute("openid", openid);
        StringBuffer pareStr = new StringBuffer();
        int numtemp = 0;
        for (String key : param.keySet()) {
            if (numtemp == 0) {
                pareStr.append(key).append("=").append(param.get(key));
            } else {
                pareStr.append("&").append(key).append("=").append(param.get(key));
            }
            numtemp++;
        }

        String reql = RequestUtil.getScheme(request)+"://"+request.getServerName() + request.getContextPath()+reqUrl;
        response.sendRedirect(reql+"?"+ pareStr.toString());
    }

}
